package org.sl.flvplayer.controls {
	import com.adobe.serialization.json.JSON;

	import org.sl.flvplayer.data.Config;
	import org.sl.flvplayer.data.VideoItem;
	import org.sl.flvplayer.flyweights.FWPlayerCommand;

	import flash.external.ExternalInterface;

	/**
	 * Enables communication with JavaScript via the ExternalInterface class and gives the possibility to load a video and control the player with JavaScript.</br> 
	 * To allow handling of the sent data JSON is used to encode and decode the string composed of commands and addtional parameters. 
	 * 
	 * @package org.sl.flvplayer.controls
	 * @author Dan
	 * @version
	 * @see org.sl.flvplayer.controls.PlayerLogic
	 */ 
	public class JavaScriptController {

		private static var instance : JavaScriptController;

		private var video : VideoItem;

		/**
		 * JavaScriptController constructor initializes the ExternalInterface by default.
		 */
		function JavaScriptController() {
			initExternalInterface();
		}

		/**
		 * Ensures that there is only one instance of the class by using the singleton pattern.
		 * 
		 * @return instance of the <code>JavaScriptController</code> class
		 */
		public static function getInstance() : JavaScriptController {
			if(!instance) instance = new JavaScriptController();			
			return instance;
		}

		/**
		 * Checks if the ExternalInterface is available and binds the JavaScript sendCommand function to the jsCommand method.
		 */
		public function initExternalInterface() : void {
			if(ExternalInterface.available) addCallback("sendCommand", jsCommand);
			else
			// FLVPlayerApplication.SOS_TRACER.error("ExternalInteface is not available in this runtime. JavaScript access is not available.");
			trace("ExternalInteface is not available in this runtime. JavaScript access is not available.");
		}

		/**
		 * Defines a callable method which can be invoked by an external JavaScript function.
		 * 
		 * @param methodName external function
		 * @param command in this case its the corresponding method 
		 */
		private function addCallback(methodName : String, command : Function) : void {
			ExternalInterface.addCallback(methodName, command);
		}	

		/**
		 * Handles commands sent by JavaScript and allows loading a new video by creating a videoNode which is processed further in a VideoItem.
		 * 
		 * @param commandString command
		 * @param p_params optional parameters
		 */
		private function jsCommand(commandString : String = "", p_params : String = null) : void {
			if (commandString == "") {
				return;			
			}
			// up to now p_params are only sent and needed when a new video has to be loaded 
			if (p_params) {
				// string gets decoded into a Object
				var params : Object = JSON.decode(p_params);			
				var previewImage : String = (params.preview_image) ? params.preview_image : "0";	
				var videoNode : XML = new XML('<video src="' + params.src + '" previewimage= "' + previewImage + '"></video>');
				videoNode.appendChild(new XML('<watermark icon= "' + params.watermark_icon + '"  iconpos= "' + params.watermark_iconpos + '"></watermark>'));
				videoNode.appendChild(new XML('<link href= "' + params.link + '"  icon= "' + params.link_icon + '"  iconpos= "' + params.link_iconpos + '"></link>'));
				videoNode.appendChild(new XML('<google track= "' + params.track + '"></google>'));
				videoNode.appendChild(new XML('<background color= "' + params.color + '"></background>'));
				// 
				video = new VideoItem(videoNode);
				var cmd : FWPlayerCommand = new FWPlayerCommand(commandString, null, [video]);
				PlayerLogic.getInstance().command(cmd);
				if(cmd.command == FWPlayerCommand.SOURCE) {
					// cmd gets overwritten
					// after the SOURCE command the RENDER command has to be executed
					cmd = new FWPlayerCommand(FWPlayerCommand.RENDER);
					PlayerLogic.getInstance().command(cmd);
					if(Config.getInstance().autoPlay) {
						cmd = new FWPlayerCommand(FWPlayerCommand.PAUSE);
						PlayerLogic.getInstance().command(cmd);
					}
				}				  				  
			} else {
				//other commands
				var _cmd : FWPlayerCommand = new FWPlayerCommand(commandString);
				PlayerLogic.getInstance().command(_cmd);
			}
		}

		/**
		 * Sends a URL string to a JavaScript function for GoogleAnalytics usage.
		 * 
		 * @param p_URL url of the current player page
		 */
		public function sendGoogleAnalyticsURL(p_URL : String) : void {
			ExternalInterface.call("pageTracker._trackPageview", p_URL);
		}
	}
}
